package com.athena.util;

import com.athena.framework.exception.BeanException;
import javassist.*;
import javassist.bytecode.CodeAttribute;
import javassist.bytecode.LocalVariableAttribute;
import javassist.bytecode.MethodInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;

public class MethodUtil {

    private final static Logger logger = LoggerFactory.getLogger(MethodUtil.class);

    /**
     * 获取参数名
     *
     * @param method
     * @return
     */
    public static String[] parameterName(Method method) {
        try {
            Class clazz = method.getDeclaringClass();
            ClassPool pool = ClassPool.getDefault();
            pool.insertClassPath(new ClassClassPath(clazz));
            CtClass cc = pool.get(clazz.getName());
            CtMethod cm = cc.getDeclaredMethod(method.getName());
            MethodInfo methodInfo = cm.getMethodInfo();
            CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
            LocalVariableAttribute attr =
                    (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
            if (attr != null) {
                String[] paramNames = new String[cm.getParameterTypes().length];
                int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
                for (int i = 0; i < paramNames.length; i++) {
                    paramNames[i] = attr.variableName(i + pos);
                }
                return paramNames;
            }
            return null;
        } catch (Exception e) {
            String msg = "获取方法参数名称失败：" + method.getName() + "\r\n" + e.getMessage();
            logger.error(msg);
            throw new BeanException(msg);
        }
    }
}
